GtkTargetList *target_list,
GdkDragAction actions,
gint button,
- GdkEvent *event)
+ GdkEvent *event,
+ int x,
+ int y)
{
GtkDragSourceInfo *info;
GList *targets = NULL;
/* Set cur_x, cur_y here so if the "drag-begin" signal shows
* the drag icon, it will be in the right place
*/
- if (event && event->type == GDK_MOTION_NOTIFY)
+ if (event)
+ info->cur_screen = gdk_event_get_screen (event);
+ else
+ gdk_device_get_position (pointer, &info->cur_screen, NULL, NULL);
+
+ if (x != -1 && y != -1)
{
- info->cur_screen = gtk_widget_get_screen (widget);
- info->cur_x = event->motion.x_root;
- info->cur_y = event->motion.y_root;
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ gtk_widget_translate_coordinates (widget, toplevel,
+ x, y, &x, &y);
+ gdk_window_get_root_coords (gtk_widget_get_window (toplevel),
+ x, y, &info->start_x, &info->start_y);
}
- else
+ else if (event && event->type == GDK_MOTION_NOTIFY)
{
- gdk_device_get_position (pointer, &info->cur_screen, &info->cur_x, &info->cur_y);
+ info->start_x = event->motion.x_root;
+ info->start_y = event->motion.y_root;
}
+ else
+ gdk_device_get_position (pointer, NULL, &info->start_x, &info->start_y);
+
g_signal_emit_by_name (widget, "drag-begin", info->context);
info->cursor = cursor;
}
}
-
+
+ info->cur_x = info->start_x;
+ info->cur_y = info->start_y;
+
if (event && event->type == GDK_MOTION_NOTIFY)
gtk_drag_motion_cb (info->ipc_widget, (GdkEventMotion *)event, info);
else
gtk_drag_update (info, info->cur_screen, info->cur_x, info->cur_y, event);
- info->start_x = info->cur_x;
- info->start_y = info->cur_y;
-
g_signal_connect (info->ipc_widget, "grab-broken-event",
G_CALLBACK (gtk_drag_grab_broken_event_cb), info);
g_signal_connect (info->ipc_widget, "grab-notify",
}
/**
- * gtk_drag_begin: (method)
+ * gtk_drag_begin_with_coordinates: (method)
* @widget: the source widget.
* @targets: The targets (data formats) in which the
* source can provide the data.
* @actions: A bitmask of the allowed drag actions for this drag.
* @button: The button the user clicked to start the drag.
* @event: The event that triggered the start of the drag.
+ * @x: The initial x coordinate to start dragging from, in the coordinate space
+ * of @widget. If -1 is passed, the coordinates are retrieved from @event or
+ * the current pointer position.
+ * @y: The initial y coordinate to start dragging from, in the coordinate space
+ * of @widget. If -1 is passed, the coordinates are retrieved from @event or
+ * the current pointer position.
*
* Initiates a drag on the source side. The function only needs to be used
* when the application is starting drags itself, and is not needed when
* The @event is used to retrieve the timestamp that will be used internally to
* grab the pointer. If @event is %NULL, then %GDK_CURRENT_TIME will be used.
* However, you should try to pass a real event in all cases, since that can be
- * used by GTK+ to get information about the start position of the drag, for
- * example if the @event is a motion event.
+ * used to get information about the drag.
*
* Generally there are three cases when you want to start a drag by hand by
* calling this function:
* Return value: (transfer none): the context for this drag.
**/
GdkDragContext *
+gtk_drag_begin_with_coordinates (GtkWidget *widget,
+ GtkTargetList *targets,
+ GdkDragAction actions,
+ gint button,
+ GdkEvent *event,
+ gint x,
+ gint y)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ g_return_val_if_fail (gtk_widget_get_realized (widget), NULL);
+ g_return_val_if_fail (targets != NULL, NULL);
+
+ return gtk_drag_begin_internal (widget, NULL, targets,
+ actions, button, event, x, y);
+}
+
+/**
+ * gtk_drag_begin: (method)
+ * @widget: the source widget.
+ * @targets: The targets (data formats) in which the
+ * source can provide the data.
+ * @actions: A bitmask of the allowed drag actions for this drag.
+ * @button: The button the user clicked to start the drag.
+ * @event: The event that triggered the start of the drag.
+ *
+ * This is equivalent to gtk_drag_begin_with_coordinates(), passing -1, -1
+ * as coordinates.
+ *
+ * Return value: (transfer none): the context for this drag.
+ *
+ * Deprecated: 3.10: Use gtk_drag_begin_with_coordinates() instead.
+ **/
+GdkDragContext *
gtk_drag_begin (GtkWidget *widget,
GtkTargetList *targets,
GdkDragAction actions,
g_return_val_if_fail (targets != NULL, NULL);
return gtk_drag_begin_internal (widget, NULL, targets,
- actions, button, event);
+ actions, button, event, -1, -1);
}
/**
{
site->state = 0;
gtk_drag_begin_internal (widget, site, site->target_list,
- site->actions,
- i, event);
+ site->actions, i, event,
+ site->x, site->y);
retval = TRUE;
}
{
icon_info->in_drag = TRUE;
icon_info->pressed = FALSE;
- gtk_drag_begin (widget,
- icon_info->target_list,
- icon_info->actions,
- 1,
- (GdkEvent*)event);
+ gtk_drag_begin_with_coordinates (widget,
+ icon_info->target_list,
+ icon_info->actions,
+ 1,
+ (GdkEvent*)event,
+ priv->start_x,
+ priv->start_y);
}
return TRUE;
priv->drag_start_x, priv->drag_start_y,
event->x + priv->scroll_offset, event->y))
{
+ gint *ranges;
+ gint n_ranges;
GdkDragContext *context;
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
guint actions = priv->editable ? GDK_ACTION_COPY | GDK_ACTION_MOVE : GDK_ACTION_COPY;
text = _gtk_entry_get_selected_text (entry);
surface = _gtk_text_util_create_drag_icon (widget, text, -1);
- context = gtk_drag_begin (widget, target_list, actions,
- priv->button, (GdkEvent *)event);
-
+ gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
+ cairo_surface_set_device_offset (surface,
+ -(priv->drag_start_x - ranges[0]),
+ -(priv->drag_start_y));
+
+ context = gtk_drag_begin_with_coordinates (widget, target_list, actions,
+ priv->button, (GdkEvent *)event,
+ priv->drag_start_x + ranges[0],
+ priv->drag_start_y);
+ g_free (ranges);
+
if (surface)
gtk_drag_set_icon_surface (context, surface);
else